package com.smasher.media

import android.content.Context
import android.media.AudioAttributes
import android.media.SoundPool
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import java.lang.ref.WeakReference

/**
 * 本地提示音播放器
 * SoundPool用于播放声音短，文件小的音频，延时短
 *
 * @author: heiyulong
 * @date: 2021/4/16
 */
class SoundPlayer(appContext: Context, maxSounds: Int, usage: Int, contentType: Int) :
    DefaultLifecycleObserver {
    private val weakReference: WeakReference<Context> = WeakReference(appContext)
    private val soundMap = HashMap<Int, Int>()

    private val audioAttributes = AudioAttributes.Builder()
        .setUsage(usage)
        .setContentType(contentType)
        .build()

    private val soundPool: SoundPool =
        SoundPool.Builder()
            .setMaxStreams(maxSounds)
            .setAudioAttributes(audioAttributes)
            .build()

    constructor(appContext: Context) : this(
        appContext,
        MAX_SOUNDS,
        AudioAttributes.USAGE_MEDIA,
        AudioAttributes.CONTENT_TYPE_MUSIC
    )

    fun attach(lifecycleOwner: LifecycleOwner) {
        lifecycleOwner.lifecycle.addObserver(this)
    }

    /**
     * 播放音频
     *
     * @param resId      音频文件 R.raw.xxx
     * @param repeatTime 循环模式：0表示播放一次，-1表示一直循环，其他表示数字+1表示当前数字对应的循环次
     */
    fun play(resId: Int, repeatTime: Int) {
        val soundID = soundPool.load(weakReference.get(), resId, 1)
        // 该方法防止sample not ready错误
        soundPool.setOnLoadCompleteListener(
            SoundPool.OnLoadCompleteListener { soundPool, sampleId, status ->
                if (status != 0) {
                    return@OnLoadCompleteListener
                }
                val streamId = soundPool?.play(
                    soundID,  //声音id
                    1f,  //左声道：0.0f ~ 1.0f
                    1f,  //右声道：0.0f ~ 1.0f
                    1,  //流优先级（0 = 最低优先级）
                    repeatTime,  //循环模式 （0 = 无循环，-1 = 永远循环）
                    1f  //播放速率（1.0 = 正常播放，范围 0.5 至 2.0）
                )
                if (streamId != null && streamId > 0) {
                    soundMap.put(resId, streamId)
                }
            })
    }

    /**
     * 播放音频
     *
     * @param resId 音频文件 R.raw.xxx
     */
    fun play(resId: Int) {
        play(resId, 0)
    }


    /**
     * 暂停
     *
     * @param resId resId
     */
    fun pause(resId: Int) {
        val mStreamID = soundMap.get(resId)
        if (mStreamID != null) {
            soundPool.pause(mStreamID)
        }
    }

    /**
     * 继续
     *
     * @param resId resId
     */
    fun resume(resId: Int) {
        val mStreamID = soundMap.get(resId)
        if (mStreamID != null) {
            soundPool.resume(mStreamID)
        }
    }

    /**
     * 停止
     *
     * @param resId resId
     */
    fun stop(resId: Int) {
        val mStreamID = soundMap.get(resId)
        if (mStreamID != null) {
            soundPool.stop(mStreamID)
        }
    }


    /**
     * 资源释放
     */
    fun release() {
        soundPool.autoPause()
        soundPool.release()
        soundMap.clear()
    }

    override fun onDestroy(owner: LifecycleOwner) {
        release()
    }

    companion object {
        private const val TAG = "SoundPlayer"
        private const val MAX_SOUNDS = 3
    }
}


